package org.wwx.client;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import org.wwx.protocol.HttpClient;
import org.wwx.register.model.ServiceInstance;

import java.lang.reflect.Type;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 注册中心客户端，提供服务的注册和发现功能
 *
 * @date 2025/6/6
 * @author王闻薪
 */
public class RegistryClient {
    private static final String REGISTRY_URL = "http://localhost:8080";
    private static final Gson gson = new GsonBuilder().create();
    private static final HttpClient httpClient = new HttpClient();

    // 注册服务实例到注册中心
    public static void registerService(String serviceName, String host, int port) {
        try {
            String url = REGISTRY_URL + "/register";

            // 构建表单参数
            Map<String, String> formData = new HashMap<>();
            formData.put("serviceName", serviceName);
            formData.put("host", host);
            formData.put("port", String.valueOf(port));

            // 发送POST请求
            String response = httpClient.postForm(url, formData);
            System.out.println("服务注册成功: " + serviceName + " - " + host + ":" + port);
            System.out.println("注册中心响应: " + response);
        } catch (Exception e) {
            System.err.println("服务注册失败: " + e.getMessage());
            e.printStackTrace();
        }
    }

    // 注销服务实例
    public static void unregisterService(String serviceName, String host, int port) {
        try {
            String url = REGISTRY_URL + "/unregister";

            // 构建表单参数
            Map<String, String> formData = new HashMap<>();
            formData.put("serviceName", serviceName);
            formData.put("host", host);
            formData.put("port", String.valueOf(port));

            // 发送POST请求
            String response = httpClient.postForm(url, formData);
            System.out.println("服务注销成功: " + serviceName + " - " + host + ":" + port);
            System.out.println("注册中心响应: " + response);
        } catch (Exception e) {
            System.err.println("服务注销失败: " + e.getMessage());
            e.printStackTrace();
        }
    }

    // 发现指定服务的所有实例
    public static List<ServiceInstance> discoverService(String serviceName) {
        try {
            String url = REGISTRY_URL + "/discover?serviceName=" + encodeParam(serviceName);

            // 发送GET请求
            String response = httpClient.get(url);

            // 解析JSON响应
            return parseServiceInstances(response);
        } catch (Exception e) {
            System.err.println("服务发现失败: " + e.getMessage());
            e.printStackTrace();
            return Collections.emptyList();
        }
    }

    // 发送心跳保持服务活跃
    public static void sendHeartbeat(String serviceName, String instanceId) {
        try {
            String url = REGISTRY_URL + "/heartbeat";

            // 构建表单参数
            Map<String, String> formData = new HashMap<>();
            formData.put("serviceName", serviceName);
            formData.put("instanceId", instanceId);

            // 发送POST请求
            httpClient.postForm(url, formData);
            System.out.println("心跳发送成功: " + instanceId);
        } catch (Exception e) {
            System.err.println("心跳发送失败: " + e.getMessage());
            e.printStackTrace();
        }
    }

    // 解析服务实例列表
    private static List<ServiceInstance> parseServiceInstances(String json) {
        try {
            // 定义JSON解析类型
            Type listType = new TypeToken<List<ServiceInstance>>(){}.getType();

            // 使用Gson解析
            return gson.fromJson(json, listType);
        } catch (Exception e) {
            System.err.println("JSON解析失败: " + e.getMessage());
            System.err.println("原始JSON: " + json);
            return Collections.emptyList();
        }
    }

    // URL参数编码
    private static String encodeParam(String param) {
        try {
            // 使用Java内置的URL编码
            return java.net.URLEncoder.encode(param, "UTF-8");
        } catch (Exception e) {
            return param; // 编码失败时返回原始参数
        }
    }

    // 获取服务实例ID（根据主机和端口生成）
    public static String getInstanceId(String host, int port) {
        return host + ":" + port;
    }
}